/*
 * Description: performance info model
 */
#ifndef PERF_INFO_H
#define PERF_INFO_H
#include <string>
#include <unordered_map>
#include <vector>
#include <set>
#include "Windows.h"
#include "performance/perf_scene.h"

namespace PERF {

constexpr const DWORD REG_DWORD_INVAILD_VALUE = 0x7fffffff;
const std::string REG_SZ_INVAILD_VALUE = " - ";

const std::string VALUE_NAME_DESCRIPTION = "Description";
const std::string VALUE_NAME_FRIENDLY_NAME = "FriendlyName";
const std::string VALUE_NAME_MANIFEST = "Manifest";
const std::string VALUE_NAME_COMMAND_LINE_SAFE = "CommandLineSafe";
const std::string VALUE_NAME_LOAD_BEHAVIOR = "LoadBehavior";

typedef enum PerfAccSkipSign : uint64_t {
    SKIP_SIGN_DEFENDER_EXCLUSION = 1 << 0,
    SKIP_SIGN_OFFICE_ADDINS = 1 << 1,
    SKIP_SIGN_ABOVE_NORMAL_PROCESS_PRIORITY = 1 << 2,
    SKIP_SIGN_FREQUENCY_INCREASING = 1 << 3,
    SKIP_SIGN_EXCLUSION_PATH = 1 << 4,
    SKIP_SIGN_EXCLUSION_PROCESS = 1 << 5,
} PerfAccSkipSign;

constexpr const DWORD SIGN_LOAD_BEHAVIOR_ENABLED = 1;

struct OfficeAddInValue {
    DWORD type;
    std::string szData{ REG_SZ_INVAILD_VALUE };
    DWORD dwData{ REG_DWORD_INVAILD_VALUE };
};

struct OfficeAddIn {
    std::string addinKeyName;
    std::unordered_map<std::string, OfficeAddInValue> nameToValue = { { VALUE_NAME_DESCRIPTION, { REG_SZ } },
                                                                      { VALUE_NAME_FRIENDLY_NAME, { REG_SZ } },
                                                                      { VALUE_NAME_MANIFEST, { REG_SZ } },
                                                                      { VALUE_NAME_LOAD_BEHAVIOR, { REG_DWORD } },
                                                                      { VALUE_NAME_COMMAND_LINE_SAFE, { REG_DWORD } } };
};

struct PerfInfo {
    /**
     * common properties
     */
    PERF_SCENE scene;
    std::string sceneStr;
    std::string appName;    //explorer.exe
    std::string appPath;    //c:\windows\system32\explorer.exe
    std::string filepath;
    std::string workFolder; //scene==appCreateFolder
    DWORD processId;        //GetCurrentProcessID
    DWORD fileSize;
    uint64_t skipSign{ 0 };
    uint64_t startMilli;
    uint64_t maxDuration{ 0 };
    std::wstring wndTextSuffix;
    std::vector<std::wstring> wndTexts;
    std::string cmdLine;

    /**
     * process priority properties
     */
    DWORD originPriority;
    /**
     * office addin properties
     */
    std::unordered_map<std::string, DWORD> addinToRegValue;
    HKEY hkUserAddin;
    HKEY hkLocalMachineAddin;
    HKEY hkLocalMachineClickToRunAddin;
    std::vector<OfficeAddIn> userAddins;
    std::vector<OfficeAddIn> localMachineAddins;
    std::vector<OfficeAddIn> localMachineClickToRunAddins;
    std::vector<OfficeAddIn> mixedAddins;
};
}  // namespace PERF
#endif